#define _CRT_SECURE_NO_WARNINGS 2
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<Functional>


using namespace std;

struct Goods
{
	string name_;
	double price_;
	int evaluate_;

	Goods(const char* str,double price,int evaluate)
		:name_(str)
		,price_(price)
		,evaluate_(evaluate)
	{}
};

void Test1()
{
	vector<Goods> v = { {"apple",8.9,9},{"pear",9.1,7},{"tomato",2.1,5} };
	sort(v.begin(), v.end(), [](const Goods& g1,const Goods& g2) {
		return g1.evaluate_ > g2.evaluate_;
		});

	sort(v.begin(), v.end(), [](const Goods& g1,const Goods& g2) {
		return g1.price_ > g2.price_;
		});
}

void Test2()
{
	int a = 1, b = 2;
	auto Swap = [](int& x, int& y) {
		int tmp = x;
		x=y;
		y = tmp;
	};
	cout << typeid(Swap).name() << endl;
	Swap(a, b);
	cout << "a:" << a << " b:" << b << endl;
}

void Test3()
{
	int x = 1, y = 2;
	auto Swap = [&x, &y]() {
		int tmp = x;
		x = y;
		y = tmp;
	}; 
	Swap();
	cout << "x:" << x << " y:" << y << endl;
}

template<class F,class T>
T useF(F f, T t)
{
	static int count = 0;
	cout <<"count:" << ++count << endl;
	cout << "&count:" << &count << endl;
	return f(t);
}

double f(double a)
{
	return a / 2;
}

struct Functor
{
	double operator()(double a)
	{
		return a / 2;
	}
};



void Test4()
{
	cout << useF(f, 10.11) << endl;
	cout << useF(Functor(), 10.10) << endl;
	cout << useF([](double x) {return x / 3; }, 10.22) << endl;
}

void Test5()
{
	function<double(double)> fun1 = f;
	useF(fun1, 10.11);

	function<double(double)> fun2 = Functor();
	useF(fun2, 10.11);

	function<double(double)> fun3 = [](double x) {return x/ 3; };
	useF(fun3, 10.22);
}

void Test6()
{
	cout << (1, 2, 3) << endl;
}

struct Date
{
public:
	Date(int year=1,int month=2,int day=3)
		:year_(year)
		,month_(month)
		,day_(day)
	{}
private:
	int year_;
	int month_;
	int day_;

};

template<class ...Args>
Date* CreateDate(Args... args)
{
	Date* date = new Date(args...);
	return date;
}

void Test7()
{
	Date* d1 = CreateDate();
	Date* d2 = CreateDate(1);
	Date* d3 = CreateDate(2,1);
	Date* d4 = CreateDate(3,1);
}

void Fun(int a, int b,int c)
{
	cout << a << endl;
	cout << b << endl;
}

class A
{
public:
	static int Add(int a, int b)
	{
		return a + b;
	}

	int sub(int a, int b)
	{
		return a - b;
	}
};

void Test8()
{
	function<void(int, int)> f1 = bind(Fun, placeholders::_1,3, placeholders::_2);
	f1(1, 2);
	function<void(int, int)> f2 = bind(Fun, placeholders::_2, 2,placeholders::_1);
	f2(1, 2);
	A aa;
	function<int(int, int)> f3 = bind(&A::Add,placeholders::_1, placeholders::_2);
	function<int(int, int)> f4 = bind(&A::sub, aa, placeholders::_1, placeholders::_2);

	f3(3, 4);
}

int main()
{
	Test8();
	return 0;
}